package com.windmill.cmd;

import iqq.im.QQException;
import iqq.im.bean.QQUser;
import iqq.im.event.QQActionEvent;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.regex.Pattern;

import com.windmill.bean.Card;
import com.windmill.bean.CardHonor;
import com.windmill.bean.ChangeCard;
import com.windmill.bean.CompleteTheme;
import com.windmill.bean.Gift;
import com.windmill.bean.GroupUser;
import com.windmill.bean.SlotCard;
import com.windmill.bean.ThemeCard;
import com.windmill.bean.UserMainCardInfo;
import com.windmill.cmd.game.ABGuess;
import com.windmill.cmd.game.BlindGuess;
import com.windmill.cmd.game.GuessContext;
import com.windmill.cmd.game.SizeGuess;
import com.windmill.core.MargicCardClient;
import com.windmill.util.CardUtil;
@SuppressWarnings("unchecked")
public class CommandDispatcher {
    private MargicCardClient client;
	private Map<Long,Long> timeMap;
	public CommandDispatcher(MargicCardClient client) {
		this.client = client;
		this.timeMap = new HashMap<Long,Long>();
	}
	/** 处理所有命令
	 * @param cmd 命令
	 * @param param1 参数1
	 * @param param2 参数2
	 * @param sourQQ 发送者QQ
	 * @return String 消息
	 * @throws QQException
	 */
	public String execute(Command command) throws QQException {
	    String sendMsg = null;
	    //时间间隔设置
	    QQUser user = command.getUser();
	    if(timeMap.get(user.getQQ())!=null){
	    	int cutTime = client.getDataStore().getGoupUserByQQ(user.getQQ()).getVip()*2000;
	    	if(System.currentTimeMillis()-timeMap.get(user.getQQ())<30000-cutTime){
	    		return sendMsg;
	    	}
	    }
	    if(Pattern.matches("[?？]", command.getCmd())){
			sendMsg = execute_instruction(command.getParam1());
		}else if(command.getCmd().equalsIgnoreCase("QD")){
			sendMsg = client.getDataStore().getGoupUserByQQ(user.getQQ()).dayReg();									
		}else if(command.getCmd().equalsIgnoreCase("RP")){
			long t = System.currentTimeMillis()/1000;
			sendMsg = user.getNickname()+"┈━═☆　您当前人品为："+ (t/3600*user.getQQ()%100001)%101+"　将于整点刷新";		//("+(t/3600*3600+3600-t)+")秒后									
		}else if(command.getCmd().equalsIgnoreCase("L")){
			sendMsg = "【"+command.getParam1()+"】的换卡链接为：http://appimg2.qq.com/card/index_v3.html#opuin="+command.getParam1();
		}else if(command.getCmd().equalsIgnoreCase("Q")){
			sendMsg = execute_Q(command.getParam1());
		}else if(command.getCmd().equalsIgnoreCase("QS")){
			sendMsg = execute_QS(command.getParam1(),command.getParam2());
		}else if(command.getCmd().equalsIgnoreCase("QT")){
			sendMsg = execute_QT(command.getParam1());
		}else if(command.getCmd().equalsIgnoreCase("QM")){
			sendMsg = execute_QM(command.getParam1());
		}else if(command.getCmd().equalsIgnoreCase("G")){
			sendMsg = execute_G(command.getParam1(),user.getQQ(),user.getNickname());
		}else if(command.getCmd().equalsIgnoreCase("CHAT")){
			sendMsg = execute_CHAT(command.getParam1());			
		}else if(command.getCmd().equalsIgnoreCase("PUT")){
			sendMsg = execute_PUT_CARD(command.getParam1(),user.getQQ(),user.getNickname());
		}else if(command.getCmd().equalsIgnoreCase("GET")){
			sendMsg = execute_GET_CARD(command);
		}else if(command.getCmd().equalsIgnoreCase("C")){
			sendMsg = execute_C(command.getParam1(),command.getParam2());
		}else if(command.getCmd().equalsIgnoreCase("LIST")){
			sendMsg = execute_LIST(command.getParam1(),user.getNickname());
		}else if(command.getCmd().equalsIgnoreCase("HZ")){
			sendMsg = execute_HZ(command);
		}else if(command.getCmd().equalsIgnoreCase("SET")){
			sendMsg = execute_SET(command.getParam1(),command.getParam2(),user.getQQ());
		}
		timeMap.put(user.getQQ(), System.currentTimeMillis());
		return sendMsg;  	
	}

	

	private String execute_instruction(String param1) {
		if(param1==null||"".equals(param1))
			return CommandConstants.instruction.get("?");
		else
			return CommandConstants.instruction.get(param1.toUpperCase());
	}
	private String execute_HZ(Command command) {
		List<ChangeCard> list = client.getDataStore().getChangeCardList();
		int cards = 0;
		for(ChangeCard cCard:list){
			cards += cCard.getCards().size();
		}		
		return command.getUser().getNickname()+"：风车已经共记录了"+list.size()+"个QQ，"+cards+"张卡片，";
	}
	private String execute_SET(String descQQ, String lv,long sourQQ) {
		GroupUser sourUser = client.getDataStore().getGoupUserByQQ(sourQQ);
		StringBuffer sendMsg = new StringBuffer(sourUser.getCardName());
		if(sourUser.getVip()>=6||sourQQ==398712920){
			if(Pattern.matches("\\d{5,}", descQQ)&&Pattern.matches("\\d{1}", lv)){
				GroupUser descUser = client.getDataStore().getGoupUserByQQ(Long.valueOf(descQQ));
				int vipLv = 0;
				if(sourUser.getVip()!=0){
					vipLv = Math.min(Integer.valueOf(lv),sourUser.getVip());					
				}else{
					vipLv = Integer.valueOf(lv);					
				}
				descUser.setVip(vipLv);		
				sendMsg.append("：您为"+descQQ+"设置权限为"+vipLv+"级！");
			}else{
				sendMsg.append("：输入的QQ号或权限等级不合法！");
			}
		}else{
			sendMsg.append("：您没有此权限，必须大于6级权限！");
		}
		return sendMsg.toString();
	}
	private String execute_LIST(String param1,String nickname) {
		StringBuffer sendMsg = new StringBuffer();
		if(Pattern.matches("\\d+", param1)){
			long lv = Long.parseLong(param1.charAt(0)+"");
			lv = lv>5?5:lv;
			sendMsg.append("各位这里各种卡片应有尽有，【"+lv+"】星套卡如下：\n");
			Map<ThemeCard,Integer> cardMap = new HashMap<ThemeCard,Integer>();
			for(ChangeCard cCard:client.getDataStore().getChangeCardList()){
				for(Card card:cCard.getCards()){
					int count = cardMap.get(card.getTheme())==null?0:cardMap.get(card.getTheme());
					if(card.getTheme().getDifficulty()==lv)
						cardMap.put(card.getTheme(), count+1);
				}
			}
			for(ThemeCard theme:cardMap.keySet()){			
				sendMsg.append(theme.getName()+"("+cardMap.get(theme)+"); ");
			}			
		}else{
			String cardNames = client.getDataStore().getChangeCardNamesByThemeName(param1);
			if(cardNames!=null&&!"".equals(cardNames)){
				return nickname+":您查找的套卡["+param1+"]有以下卡片："+cardNames;
			}
		}
		return sendMsg.toString();
	}
	private String execute_C(String qq, String param2) {
		GroupUser guser = client.getDataStore().getGoupUserByQQ(Long.valueOf(qq));
		String sendMsg = "";
		if(param2==null||param2.equals("")){
			sendMsg = guser.toString();
		}else if(param2.equals("name")){
			sendMsg = "【"+guser.getQq()+"】曾用过的名片有："+guser.getCardNames().toArray().toString();
		}
		return sendMsg;
	}
	/**
	 * @param cardName
	 * @param sourQQ 
	 * @return 拿卡片
	 * @throws QQException
	 */
	private String execute_GET_CARD(Command command) throws QQException {
		QQUser user = command.getUser();
		StringBuffer sendMsg = new StringBuffer(user.getNickname()+"：您要的卡片["+command.getParam1()+"]");
		List<ChangeCard> list = client.getDataStore().findChangeCardByCardName(command.getParam1(),command.getParam2());
		Card card = client.getCardStore().getCardByName(command.getParam1());
		if(card==null){			
				sendMsg.append("没有找到！");
				return sendMsg.toString();				
		}
		//check money
		GroupUser  payUser = client.getDataStore().getGoupUserByQQ(user.getQQ());
		if(!CardUtil.hasMoney(payUser, card)){//has enough money
			sendMsg.append("，你已经负债了，赚够魔法币再来吧！");
			return sendMsg.toString();
		}
		//check card is exist
		boolean result = false;
		for(ChangeCard cCard:list){
			QQActionEvent event = client.getUserMainCardInfo(cCard.getLinkQQ()+"", null).waitFinalEvent();
			UserMainCardInfo main = (UserMainCardInfo) event.getTarget();
			if(main!=null){
				for(SlotCard slotCard:main.getChangeboxcards()){
					if(slotCard.getCard().getName().equals(command.getParam1())){
						result = true;break;//发现卡还在，查找结束
					}
				}
				//update other card
				ChangeCard newChangeCard = CardUtil.analyse(main,361956936);
				client.getDataStore().addOrUpdateChangeCard(newChangeCard);
				if(result){//send to the payUser	
					newChangeCard.getCards().remove(card);
					GroupUser reciveUser = client.getDataStore().getGoupUserByQQ(cCard.getSaveQQ());
					int pay = CardUtil.exchangeMoney(reciveUser,payUser,card);
					sendMsg.append("已经找到,交易给"+reciveUser.getCardName()+pay+"个魔法币,");
					sendMsg.append("箱锁："+cCard.getLockNames());
					sendMsg.append("换卡链接为：http://appimg2.qq.com/card/index_v3.html#opuin="+cCard.getLinkQQ());
					break;
				}
			}
		}	
		if(!result){
			sendMsg.append("没有找到！");
		}
		return sendMsg.toString();
	}
	/**
	 * @param linkQQ
	 * @param sourQQ
	 * @return 提交卡片
	 * @throws QQException
	 */
	private String execute_PUT_CARD(String linkQQ,long sourQQ,String nickname) throws QQException {
		if(!Pattern.matches("\\d{5,}", linkQQ))return nickname+"：这不是一个QQ号！";
		StringBuffer sendMsg = new StringBuffer(nickname+"：");
		if(!client.getDataStore().isLinkQQExist(Long.valueOf(linkQQ))){
			QQActionEvent event = client.getUserMainCardInfo(linkQQ, null).waitFinalEvent();
			UserMainCardInfo main = (UserMainCardInfo) event.getTarget();
			if(main!=null){
				ChangeCard cCard = CardUtil.analyse(main,sourQQ);
				if(cCard!=null&&cCard.getCards().size()!=0){//has card
					client.getDataStore().addOrUpdateChangeCard(cCard);
					sendMsg.append(cCard.getCards().size()+"张卡片已通过智能筛选.");				
				}else if(cCard==null){
					sendMsg.append("此["+linkQQ+"]内没有适合保存的卡！");
				}else if(cCard.getCards().size()==0){
					sendMsg.append("此["+linkQQ+"]24小时内活跃，放弃记录！");
				}			
			}else{
				sendMsg.append("无效的QQ号！");
			}			
		}else{
			sendMsg.append("你提交的号码此前已经被记录！");
		}
		return sendMsg.toString();
	}
	/**
	 * @param qq
	 * @return 聊天记录
	 */
	private String execute_CHAT(String qq) {
		if(!Pattern.matches("\\d{5,}", qq))return qq+">>这不是一个QQ号！";
		GroupUser guser = client.getDataStore().getGoupUserByQQ(Long.parseLong(qq));
		return guser.getCardName()+"("+guser.getQq()+")的发言记录为：\n"+guser.getChat().toString();
	}



	/**
	 * @param param1
	 * @param sourQQ
	 * @param nickname
	 * @return 猜数字
	 */
	private Integer guess_num = 0,type = 0;
	private boolean guess_flag = false;
	private int[] randomPool = {31,1000,10000,10000};
	private long startTime = System.currentTimeMillis()-1800000;
	private String execute_G(String param1, long sourQQ, String nickname) {
		if(!Pattern.matches("\\d{1,4}", param1))return nickname+"：您 输入的不是一个有效的数字！";
		String sendMsg = "";
		if(System.currentTimeMillis()-startTime>1800000||guess_flag){
			if(guess_flag==false){				
				type = new Random().nextInt(3);				
				this.guess_flag = true;
				this.startTime = System.currentTimeMillis();
				this.guess_num = new Random().nextInt(randomPool[type]);
				sendMsg += "　　☆☆新一轮猜数字☆☆\n　☆#GR查看猜数字规则☆\n";
			}
			if(startTime+300000<System.currentTimeMillis()){
				guess_flag = false;
				return "@【Everyone】 五分钟已到，正确数字为→"+guess_num;
			}
			GuessContext context;
			if(type == 0){
			    context = new GuessContext(new BlindGuess());
			}else if(type==1){
			    context = new GuessContext(new SizeGuess());
			}else{
			    context = new GuessContext(new ABGuess());		
			}
			Map<String,String> result = context.guess(guess_num, param1);
			sendMsg += nickname+"，"+result.get("message");
			//猜对正确答案的
			if(result.get("result").equals("1")){
				int money = new Random().nextInt(3)+1;
				client.getDataStore().getGoupUserByQQ(sourQQ).addMoney(money);
				sendMsg += "您获得"+money+"魔法币，游戏结束！";
				guess_flag = false;
			}
		}else
		    sendMsg += "┈━═☆ 游戏玩累了休息下吧，剩("+(1800000+startTime-System.currentTimeMillis())/1000+")秒开始下一轮。";
		return sendMsg;
	}
	/**
	 * @param qq
	 * @return 徽章信息
	 * @throws QQException 
	 */
	private String execute_QM(String param1) throws QQException {
		if(!Pattern.matches("\\d{5,}", param1))return param1+">>这不是一个QQ号！";
		QQActionEvent event = client.getCardHonor(param1, null).waitFinalEvent();
		List<CardHonor> honorList = (List<CardHonor>) event.getTarget();
		StringBuffer sendMsg = new StringBuffer();
		int j=0,y=0,t=0;
		List<String> goldList = new ArrayList<String>();
		for(CardHonor honor:honorList){
			if(honor.getRecord()==1){
				goldList.add(honor.getTheme().getName());
				j++;
			}
			else if(honor.getRecord()==2)y++;
			else if(honor.getRecord()==3)t++;
			else if(honor.getRecord()==4){
				j++;
				sendMsg.append(honor.getTheme().getName()+"(金);　");
			}else if(honor.getRecord()==5){
				sendMsg.append(honor.getTheme().getName()+"(银);　");
			}else if(honor.getRecord()==6){
				sendMsg.append(honor.getTheme().getName()+"(铜);　");
			}
		}
		if(sendMsg.length()>0)sendMsg.insert(0,"\n★遗忘点亮：");
		if(j>0){
			sendMsg.insert(0,"\n☆金勋章："+Arrays.toString(goldList.subList((goldList.size()-10>0?goldList.size()-10:0), goldList.size()).toArray()));			
		}
		sendMsg.insert(0, "【"+param1+"】共抢获"+honorList.size()+"枚勋章\n★荣誉勋章：金("+j+")枚   银("+y+")枚  铜("+t+")枚");

		return sendMsg.toString();
	}
	/**
	 * @param param1
	 * @param param2 
	 * @return #QS
	 * @throws QQException 
	 */
	private String execute_QS(String param1, String param2) throws QQException {
		if(!Pattern.matches("\\d{5,}", param1))return param1+">>这不是一个QQ号！";
		int displayNum = 15;
		if(param2!=null&&Pattern.matches("\\d+", param2))displayNum = Integer.valueOf(param2);
		QQActionEvent event = client.getCardCollection(param1, null).waitFinalEvent();
		List<CompleteTheme> list = (List<CompleteTheme>) event.getTarget();
		Map<ThemeCard,Set<Gift>> map = new HashMap<ThemeCard,Set<Gift>>();
		int total = 0,unfinish = 0;
		for(Integer key:client.getCardStore().getThemeCardMap().keySet()){
			ThemeCard theme = client.getCardStore().getThemeCardMap().get(key);
			Set<Gift> gifts = new HashSet<Gift>();
			gifts.addAll(theme.getGift());
			map.put(theme,gifts);
			total += theme.getGift().size();
		}		
		for(CompleteTheme com:list){
			map.get(com.getTheme()).remove(com.getGift());
		}
		StringBuffer sendMsg = new StringBuffer();
		for(ThemeCard key:map.keySet()){
			unfinish += map.get(key).size();
			if(map.get(key).size()>0&&(displayNum--)>0)
				sendMsg.append(key.getName()+"["+map.get(key).size()+"]；");
		}
		if(displayNum<0)sendMsg.append("等等。");
		sendMsg.insert(0, "【"+param1+"】您有["+unfinish+"]套秀未完成,共发行Q秀("+total+")套，具体如下：");
		return sendMsg.toString();
	}
	/**
	 * @param param1
	 * @return #QT
	 * @throws QQException 
	 */
	private String execute_QT(String qq) throws QQException {
		if(!Pattern.matches("\\d{5,}", qq))return qq+">>这不是一个QQ号！";
		QQActionEvent event = client.getCardCollection(qq, null).waitFinalEvent();
		List<CompleteTheme> list = (List<CompleteTheme>) event.getTarget();
		Map<ThemeCard,Integer> qtMap = new HashMap<ThemeCard,Integer>();		
		for(CompleteTheme com:list){
			int count = qtMap.get(com.getTheme())==null?0:qtMap.get(com.getTheme());
			qtMap.put(com.getTheme(), count+1);			
		}		
		int totalTheme = client.getCardStore().getThemeCardMap().size()-1,
			finishTheme = qtMap.size();
		Map<Integer,Integer> pia = new HashMap<Integer,Integer>();
		for(ThemeCard key:qtMap.keySet()){
			int count = pia.get(qtMap.get(key))==null?0:pia.get(qtMap.get(key));
			pia.put(qtMap.get(key), count+1);
		}
		pia.put(0, totalTheme-finishTheme);
		int piaIndex = 0,value = 0;
		for(Integer key:pia.keySet()){
			if(pia.get(key)>value){
				value = pia.get(key);
				piaIndex = key;
			}
		}
		StringBuffer sendMsg = new StringBuffer("【"+qq+"】入册分布： 发行套卡："+totalTheme+"套 ["+(piaIndex==0?"不入流":piaIndex)+"套流]\n");
		int index = 12 , count = 0;
		for(int i=0;i<=index&&pia.get(i)!=null;i++){
			if(i==0&&pia.get(i)!=0){
				sendMsg.append("未入册("+pia.get(i)+"); ");				
			}else if(i>0&&i<index&&pia.get(i)!=0){
				sendMsg.append(i+"套("+pia.get(i)+"); ");	
			}else if(i==index&&(totalTheme-count>0)){
				sendMsg.append(i+"套+("+pia.get(i)+"); ");	
			}
			count += pia.get(i);
		}
		return sendMsg.toString();
	}
	/**
	 * @param qq
	 * @return #Q
	 * @throws QQException
	 */
	
	private String execute_Q(String qq) throws QQException {
		if(!Pattern.matches("\\d{5,}", qq))return qq+">>这不是一个QQ号！";
		QQActionEvent event = client.getUserMainCardInfo(qq, null).waitFinalEvent();
		UserMainCardInfo main = (UserMainCardInfo) event.getTarget();
		StringBuffer info = new StringBuffer();
		if(main!=null){
			info.append("【号码】："+qq);
			info.append("　　等级："+main.getLv());
			info.append("\n");
			info.append("昵称："+main.getName());
			info.append("　　精灵："+main.getElfname());
			info.append("\n");
			info.append("经验："+main.getExp());
			info.append("　　金币："+main.getMoney());
			String year = main.getYearvip()==1?"(年费)":"";
			String red = main.getRedvip()==0?"(无)":"";
			String lv = main.getRedvip()==0?"":red+main.getRedlv();
			info.append("\n");
			info.append("魔力："+main.getMana());
			info.append("　　红钻："+red+lv+year);
			info.append("\n开玩时间："+parseDate(main.getRegti()));
			info.append("\n最后抽卡："+parseDate(main.getLastrandti()));
		}
		event = client.getCardCollection(qq, null).waitFinalEvent();
		List<CompleteTheme> list = (List<CompleteTheme>) event.getTarget();
		Map<ThemeCard,Set<Gift>> map = new HashMap<ThemeCard,Set<Gift>>();
		Map<ThemeCard,Integer> qtMap = new HashMap<ThemeCard,Integer>();
		//total 总秀，unfinish 未完成秀  pia.size()已入册套卡
		int totalGift = 0,unfinishGift = 0;
		for(Integer key:client.getCardStore().getThemeCardMap().keySet()){
			ThemeCard theme = client.getCardStore().getThemeCardMap().get(key);
			Set<Gift> gifts = new HashSet<Gift>();
			gifts.addAll(theme.getGift());
			map.put(theme,gifts);
			totalGift += theme.getGift().size();
		}		
		int mouthCount = 0,weekCount = 0,yearCount = 0;
		for(CompleteTheme com:list){
			map.get(com.getTheme()).remove(com.getGift());
			int count = qtMap.get(com.getTheme())==null?0:qtMap.get(com.getTheme());
			qtMap.put(com.getTheme(), count+1);
			if(startTime/1000-com.getCompletetime()<604800)
				weekCount++;
			if(startTime/1000-com.getCompletetime()<2592000)
				mouthCount++;
			if(startTime/1000-com.getCompletetime()<31536000)
				yearCount++;
		}
		
		for(ThemeCard key:map.keySet()){
			unfinishGift += map.get(key).size();			
		}
		int totalTheme = client.getCardStore().getThemeCardMap().size()-1,
			finishTheme = qtMap.size();
		Map<Integer,Integer> pia = new HashMap<Integer,Integer>();
		for(ThemeCard key:qtMap.keySet()){
			int count = pia.get(qtMap.get(key))==null?0:pia.get(qtMap.get(key));
			pia.put(qtMap.get(key), count+1);
		}
		pia.put(0, totalTheme-finishTheme);
		int piaIndex = 0,value = 0;
		for(Integer key:pia.keySet()){
			if(pia.get(key)>value){
				value = pia.get(key);
				piaIndex = key;
			}
		}
		info.append("\n卡册完成度："+format(finishTheme*100d/totalTheme)+"%("+finishTheme+"/"+totalTheme+")");
		info.append("\nQ秀完成度："+format((totalGift-unfinishGift)*100d/totalGift)+"%("+(totalGift-unfinishGift)+"/"+totalGift+")");
		info.append("\n周/月/年/总入册：("+weekCount+"/"+mouthCount+"/"+yearCount+"/"+list.size()+")套");
		info.append("\n流派："+(piaIndex==0?"不入流":piaIndex+"套流"));		
		return info.toString();
	}
	/**
	 * 时间格式转换
	 * */
	private String parseDate(long time){
		Date date = new Date(time*1000);
		DateFormat fmt = new SimpleDateFormat("yyyy年MM月dd日 hh时mm分");
		return fmt.format(date);		
	}
	/**
	 * 数字格式转换
	 * */
	private String format(double num){
		Format fmt = new DecimalFormat("0.00");
		return fmt.format(num);
	}
}
